package utils

import (
	"fmt"
	"net"
	"strconv"
	"strings"
)

// ParseAddress 解析十六进制地址为IP地址和端口
func ParseAddress(addrStr string) (string, int, error) {
	parts := strings.Split(addrStr, ":")
	if len(parts) != 2 {
		return "", 0, fmt.Errorf("地址格式错误")
	}

	// 解析IP地址（十六进制）
	ipHex := parts[0]
	// 解析端口（十六进制）
	portHex := parts[1]

	// 转换端口
	port, err := strconv.ParseUint(portHex, 16, 16)
	if err != nil {
		return "", 0, fmt.Errorf("解析端口失败: %v", err)
	}

	// 转换IP地址
	var ip string
	if len(ipHex) == 8 {
		// IPv4
		ip = ParseIPv4(ipHex)
	} else if len(ipHex) == 32 {
		// IPv6
		ip = ParseIPv6(ipHex)
	} else {
		return "", 0, fmt.Errorf("未知IP地址格式")
	}

	return ip, int(port), nil
}

// ParseIPv4 解析IPv4地址
func ParseIPv4(hexStr string) string {
	if len(hexStr) != 8 {
		return "0.0.0.0"
	}

	// 解析为uint32然后转换为IP
	ipInt, err := strconv.ParseUint(hexStr, 16, 32)
	if err != nil {
		return "0.0.0.0"
	}

	// 转换字节序（小端序）
	ip := net.IPv4(
		byte(ipInt&0xFF),
		byte((ipInt>>8)&0xFF),
		byte((ipInt>>16)&0xFF),
		byte((ipInt>>24)&0xFF),
	).String()

	return ip
}

// ParseIPv6 解析IPv6地址
func ParseIPv6(hexStr string) string {
	if len(hexStr) != 32 {
		return "::"
	}

	// 将十六进制字符串转换为16个字节
	bytes := make([]byte, 16)
	for i := 0; i < 16; i++ {
		v, err := strconv.ParseUint(hexStr[i*2:(i*2)+2], 16, 8)
		if err != nil {
			return "::"
		}
		bytes[i] = byte(v)
	}

	// 使用net.IP来正确处理IPv6地址
	ip := net.IP(bytes)

	// 检查是否为IPv4映射到IPv6的地址 (::ffff:x.x.x.x)
	if ipv4 := ip.To4(); ipv4 != nil {
		return ip.String()
	}

	// 检查是否为全零地址
	if ip.IsUnspecified() {
		return "::"
	}

	// 返回IPv6地址的标准格式
	return ip.String()
}

// ParseConnectionState 解析连接状态
func ParseConnectionState(stateHex, protocol string) string {
	state, err := strconv.ParseUint(stateHex, 16, 8)
	if err != nil {
		return "UNKNOWN"
	}

	if protocol == "udp" || protocol == "udp6" {
		switch state {
		case 7:
			return "UNCONN"
		default:
			return "UNKNOWN"
		}
	}

	// TCP 状态
	switch state {
	case 1:
		return "ESTABLISHED"
	case 2:
		return "SYN_SENT"
	case 3:
		return "SYN_RECV"
	case 4:
		return "FIN_WAIT1"
	case 5:
		return "FIN_WAIT2"
	case 6:
		return "TIME_WAIT"
	case 7:
		return "CLOSE"
	case 8:
		return "CLOSE_WAIT"
	case 9:
		return "LAST_ACK"
	case 10:
		return "LISTEN"
	case 11:
		return "CLOSING"
	default:
		return "UNKNOWN"
	}
}
